using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ebcpatterns.concurrent;
using csvviewer.adapter;
using csvviewer.logic;
using csvviewer.portal;
using csvviewer.app.infrastructure;

namespace csvviewer.app
{
    class Program
    {
        static void Main(string[] args)
        {
			// Build
            var run = new Run();
			var config = new Config(args);
			var init = new Initialize();
			
			var async = new Asynchronizer();
			
            var parse = new Parse_command_line();
            var readPos = new Read_line_positions_from_file();
			//var prepend = new Prepend_line_index();
            var buffer = new Buffer_lines();
			
			var calc = new Calc_index_of_first_line_of_page();
			var getLines = new Get_page_line_positions_from_buffer();
			var readPage = new Read_page_lines_from_file();
            var @get = new Get_page_from_buffer(
								calc, 
								getLines,
				                readPage);
			
            var format = new Format_page(
								new Prepend_line_index(),
								new Parse_lines(), 
								new Normalize_columns(), 
								new Format_table());
			
            var ui = new UI();

            // Bind
			config.WithArgs += parse.Process;
			parse.Filename += readPos.Config;
			parse.Filename += readPage.Config;
            parse.PageLength += calc.Config;
			
            init.WithoutArgs += async.Process;
			async.Result += readPos.Process;            
			readPos.LinePosition += buffer.Process;
            buffer.Continue += @get.TurnToPage;
            @get.Page += format.Process;
            format.Table += ui.ScheduleDisplay;
			ui.TurnToPage += @get.TurnToPage;
			ui.JumpToPage += @get.JumpToPage;
			
			run.WithoutArgs += ui.Run;
            
			// Inject
            var lineBuffer = new ConcurrentList<long>();
            buffer.Inject(lineBuffer);
            calc.Inject(lineBuffer);
			getLines.Inject(lineBuffer);

			// Config
            config.Process();
			
			// Initialize
			init.Process();
			
			// Run
			run.Process();
        }
    }
}
